﻿//TODO: Maybe it could be sped up?!, Ranking

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Ranking filter
    /// </summary>
    public class Ranking : BaseImageFilter
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Ranking"/> class.
        /// </summary>
        public Ranking()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Ranking"/> class.
        /// </summary>
        /// <param name="_ranking">The _ranking.</param>
        internal Ranking(Ranking _ranking)
        {
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;

            int nHeight = _bitmap.Height;
            int nWidth = _bitmap.Width;
            int n = 0;
            int[,] help = new int[nWidth, nHeight];
            int[] a = new int[9];
            int m_nY = 0;
            int m_nX = 0;

            for (m_nY = 0; m_nY < nHeight; m_nY++)
            {
                for (m_nX = 0; m_nX < nWidth; m_nX++)
                {
                    n = 0;
                    Array.Clear(a, 0, 9);

                    if (m_nX - 1 >= 0 && m_nY - 1 >= 0) a[n++] = bitmap.GetPixel(m_nX - 1, m_nY - 1).ToArgb();

                    if (m_nY - 1 >= 0) a[n++] = bitmap.GetPixel(m_nX, m_nY - 1).ToArgb();

                    if (m_nX + 1 < nWidth && m_nY - 1 >= 0) a[n++] = bitmap.GetPixel(m_nX + 1, m_nY - 1).ToArgb();

                    if (m_nX - 1 >= 0) a[n++] = bitmap.GetPixel(m_nX - 1, m_nY).ToArgb();

                    a[n++] = bitmap.GetPixel(m_nX, m_nY).ToArgb();

                    if (m_nX + 1 < nWidth) a[n++] = bitmap.GetPixel(m_nX + 1, m_nY).ToArgb();

                    if (m_nX - 1 >= 0 && m_nY + 1 < nHeight) a[n++] = bitmap.GetPixel(m_nX - 1, m_nY + 1).ToArgb();

                    if (m_nY + 1 < nHeight) a[n++] = bitmap.GetPixel(m_nX, m_nY + 1).ToArgb();

                    if (m_nX + 1 < nWidth && m_nY + 1 < nHeight) a[n++] = bitmap.GetPixel(m_nX + 1, m_nY + 1).ToArgb();
                    Array.Sort(a, 0, n);
                    help[m_nX, m_nY] = a[n / 2];
                }
            }

            for (m_nY = 0; m_nY < nHeight; m_nY++)
            {
                for (m_nX = 0; m_nX < nWidth; m_nX++)
                {
                    bitmap.SetPixel(m_nX, m_nY, Color.FromArgb(help[m_nX, m_nY]));
                }
            }
            return _bitmap;
        }

        /// <summary>
        /// Used to clone this instance
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new Ranking();
        }
    }
}
